home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / What's New / Tool Chest / Testing & Debugging / Debuggers & dcmds / MacsBug 6.5.4a3 / Building dcmds / C Samples / File.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-03  |  10.9 KB  |  424 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     File:        File.c
  4.  
  5.     Contains:    This is the FCB dcmd.
  6.  
  7.     Written by:    JM3 = Jim Murphy
  8.                 DAL = Dave Lyons
  9.                 sad = Scott Douglas
  10.  
  11.     Copyright:    © 1988,1993-1996 by Apple Computer, Inc., all rights reserved.
  12.  
  13.     Change History (most recent first):
  14.  
  15.         <12>     5/23/96    DAL        Tolerate System 8 weirdness (d11e4) in FSFCBLen by making it a
  16.                                     warning instead of fatal, and fix FSFCBLen warning to really be
  17.                                     a PString. Version 3.0.3d1.
  18.         <11>   27-Jan-96    JM3        And the project lead declared, “alpha! beta! final! GM!”
  19.         <10>   25-Jan-96    JM3        Added sample build commands.
  20.          <9>     10/5/95    DAL        Made source legible. Options still don't combine, though. Could
  21.                                     use more work, but it's mo-better than before.
  22.          <8>     10/4/95    DAL        Added -t type option. Version 3.0.2d1. Ya know, this command is
  23.                                     *really* unreadable, thanks in large part to me. It is begging
  24.                                     to be whaled upon mightily...de-elsed and disentangled. There
  25.                                     are now enough options that the combinations should work, like
  26.                                     'file "Sys" -t MACS', but they don't combine.
  27.          <7>     4/18/95    DAL        Omit some boring fields from the "file 0" display (for logs).
  28.          <6>     2/21/95    DAL        Made "file 0" show all open files except for fonts (to help
  29.                                     shrink Standard Logs). Bumped version to 3.0.1.
  30.          <5>   10-Dec-94    JM3        Updated for new format 3 dcmd requirements.
  31.          <4>     5/13/94    DAL        Deal with carriage returns inside filenames (changed put.c).
  32.          <3>   24-Jan-94    JM3        With the Universal Interfaces, EqualString is now in
  33.                                     TextUtils.h. Blah.
  34.          <2>     9/13/93    DAL        made some columns wider and fixed the filename-prefix feature to
  35.                                     work again
  36.  
  37.     Old history:
  38.  
  39.         29Nov88 sad        revised for new dcmd names.
  40.          5Oct88    sad        broke out formatting routines to put.c
  41.         30Sep88 sad        written
  42.  
  43.     The following MPW commands will build the dcmd and copy it to the "Debugger Prefs" file
  44.     in the System folder. The dcmd's name in MacsBug will be the name of the file built by
  45.     the Linker.
  46.  
  47.     C File.c
  48.     Link -o File -sg Main=STDCLIB,STDIO,SANELIB dcmdGlue.a.o File.c.o Put.c.o ∂
  49.         "{Libraries}Runtime.o" "{Libraries}Interface.o"
  50.     BuildDcmd File 194 -format3
  51.     Echo 'include "File";'    |    Rez -a -o "{SystemFolder}Debugger Prefs"
  52.  
  53. */
  54.  
  55. #include <Types.h>
  56. #include <Memory.h>
  57. #include <Files.h>
  58. #include <OSUtils.h>
  59. #include <TextUtils.h>
  60.  
  61. #include "dcmd.h"
  62. #include "put.h"
  63.  
  64.  
  65. //----------------------------------------------------------------------------------------
  66. // ••• Lomem stuff •••
  67. //----------------------------------------------------------------------------------------
  68.  
  69. #define FSFCBLen 0x3f6
  70. #define FCBsPtr  0x34e
  71.  
  72.  
  73. typedef struct FCB
  74. {
  75.     unsigned long fcbFlNum;
  76.     unsigned char fcbMdRByt;
  77.     unsigned char fcbTypByt;
  78.     unsigned short fcbSBlk;
  79.     unsigned long fcbEOF;
  80.     unsigned long fcbPLen;
  81.     unsigned long fcbCrPs;
  82.     VCB* fcbVPtr;
  83.     void* fcbBfAdr;
  84.     unsigned short fcbFlPos;
  85.     unsigned long fcbClmpSize;
  86.     void* fcbBTCBPtr;
  87.     unsigned long fcbExtRec[3];
  88.     OSType fcbFType;
  89.     unsigned long fcbCatPos;
  90.     unsigned long fcbDirID;
  91.     char fcbCName[32];
  92. }
  93.     FCB;
  94.  
  95.  
  96. //----------------------------------------------------------------------------------------
  97. // DrawHeader:
  98. //----------------------------------------------------------------------------------------
  99. static void DrawHeader(Boolean shortForm)
  100. {
  101. //                                 1         2         3         4         5         6         7
  102. //                        1234567890123456789012345678901234567890123456789012345678901234567890
  103.  
  104.     if (shortForm)
  105.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof");
  106.     else
  107.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof     Mark  FlNum Parent FCB at");
  108. }
  109.  
  110.  
  111. //----------------------------------------------------------------------------------------
  112. // IsFontFile:
  113. //----------------------------------------------------------------------------------------
  114. static Boolean IsFontFile(FCB *fcbp)
  115. {
  116.     OSType filetype = fcbp->fcbFType;
  117.  
  118.     if (filetype == 'FFIL' || filetype == 'ffil' || filetype == 'tfil')
  119.         return true;
  120.  
  121.     return false;
  122. }
  123.  
  124.  
  125. //----------------------------------------------------------------------------------------
  126. // DrawFCB:
  127. //----------------------------------------------------------------------------------------
  128. static void DrawFCB(int fref, FCB* fcbp, Boolean shortForm)
  129. {
  130.     PutUHexWord(fref);
  131.     PutSpace();
  132.     PutPStrTruncTo(fcbp->fcbCName, 17+10);
  133.     PutSpace();
  134.     PutPStrTruncTo(fcbp->fcbVPtr->vcbVN, 26+10+3);
  135.     PutSpace();
  136.     PutOSType(fcbp->fcbFType);
  137.     PutSpace();
  138.     PutChar((fcbp->fcbMdRByt & 0x80) ? 'D' : 'd');
  139.     PutChar((fcbp->fcbMdRByt & 0x01) ? 'W' : 'w');
  140.     PutSpace();
  141.     if (fcbp->fcbMdRByt & 0x02)
  142.         PutPStr("\prsrc ");
  143.     else
  144.         PutPStr("\pdata ");
  145.     PutUDecTo(fcbp->fcbEOF,47+11+3);
  146.  
  147.     if (!shortForm)
  148.     {
  149.         PutSpace();
  150.         PutUDecTo(fcbp->fcbCrPs,55+12+3);
  151.         PutSpace();
  152.         PutUHexZTo(fcbp->fcbFlNum,6,62+12+3);
  153.         PutSpace();
  154.         PutUHexZTo(fcbp->fcbDirID,6,69+12+3);
  155.         PutSpace();
  156.         PutUHexZTo((unsigned long)fcbp,6,76+12+3);
  157.     }
  158.  
  159.     PutLine();
  160. }
  161.  
  162.  
  163. //----------------------------------------------------------------------------------------
  164. // PrefixPStr
  165. //         returns true if astr is equal to a prefix of bstr.
  166. //        (astr must not be longer than 31 characters)
  167. //----------------------------------------------------------------------------------------
  168. static Boolean PrefixPStr(const Str255 astr, const Str255 bstr)
  169. {
  170.     char newstr[31];
  171.     int alen = *astr;
  172.     int blen = *bstr;
  173.  
  174.     if (alen <= blen)
  175.     {
  176.         BlockMoveData(bstr+1, newstr+1, alen);
  177.         newstr[0] = alen;
  178.         return EqualString(astr, newstr, false, true);
  179.     }
  180.  
  181.     return false;    
  182. }
  183.  
  184.  
  185. //----------------------------------------------------------------------------------------
  186. // DoHelp:
  187. //----------------------------------------------------------------------------------------
  188. static void DoHelp(void)
  189. {
  190.     dcmdDrawLine("\pDisplays file information on all open files, or for the given fRefNum,");
  191.     dcmdDrawLine("\pfilename, or for all files of the given filetype. Flags are D/d=Dirty,");
  192.     dcmdDrawLine("\pW/w=writeable.  \"file 0\" shows all open files except for fonts.");
  193. }
  194.  
  195.  
  196.  
  197. //----------------------------------------------------------------------------------------
  198. // ••• parsed options •••
  199. //----------------------------------------------------------------------------------------
  200.  
  201. Boolean gDoOneFCB, gHaveFileName;
  202. OSType gFiletype;
  203. long gRefnum;
  204.  
  205.  
  206. //----------------------------------------------------------------------------------------
  207. // DoFileCommand:
  208. //----------------------------------------------------------------------------------------
  209. void DoFileCommand(dcmdBlock *paramPtr)
  210. {
  211.     short    c;
  212.     int        fcbLen;                // the length of one fcb
  213.     char*    fcbsbase;
  214.     int        fcbslen;            // the length of the fcbs block
  215.     Str255    filename;
  216.  
  217.     gDoOneFCB = false;
  218.     gHaveFileName = false;
  219.     gFiletype = 0;
  220.  
  221.     dcmdDrawLine("\pDisplaying File Control Blocks");
  222.  
  223.     fcbLen   = * (unsigned short *) FSFCBLen;
  224.     fcbsbase = * (char **) FCBsPtr;
  225.     fcbslen  = * (unsigned short *) fcbsbase;
  226.  
  227.     if (fcbLen != sizeof(FCB))
  228.     {
  229.         PutPStr("\pNote: FSFCBLen = ");
  230.         PutUDec(fcbLen);
  231.         PutPStr("\p expected ");
  232.         PutUDec(fcbLen);
  233.         PutLine(sizeof(FCB));
  234.  
  235.         // return;    // keep going anyway (23-May-96 DAL)
  236.         
  237.         if (fcbLen > 0x7000)        // screwy version of Maxwell
  238.         {
  239.             fcbLen = 0x5E;        // use standard value
  240.         }
  241.     }
  242.  
  243.     if ((fcbslen - 2) % fcbLen != 0)
  244.     {
  245.         PutPStr("\pBad fcbslen ");
  246.         PutUHexWord(fcbslen);
  247.         PutLine();
  248.         return;
  249.     }
  250.  
  251.     c = dcmdPeekAtNextChar();
  252.     if (c == '"' || c == '\'')
  253.     {
  254.         gHaveFileName = true;
  255.         (void) dcmdGetNextParameter(filename);    // get the filename ('file "name"')
  256.     }
  257.     else if (c == '-')        // look for "-t type"
  258.     {
  259.         dcmdGetNextParameter(filename);
  260.         if (filename[0] != 2 || filename[1] != '-' || filename[2] != 't')    // not "-t" ?
  261.         {
  262.             PutPStr("\pBad option");
  263.             PutLine();
  264.             return;
  265.         }
  266.  
  267.         dcmdGetNextParameter(filename);        // get the filetype ('file -t type')
  268.         gFiletype = '    ';
  269.         if (filename[0] == 0 || filename[0] > 4)
  270.         {
  271.             PutPStr("\pBad filetype");
  272.             PutLine();
  273.             return;
  274.         }
  275.  
  276.         BlockMoveData(&filename[1], &gFiletype, filename[0]);
  277.     }
  278.     else
  279.     {
  280.         (void) dcmdGetNextExpression(&gRefnum, &gDoOneFCB);        // get single file refnum
  281.     }
  282.  
  283.  
  284.     // ••• handle 'file <refnum>' (display info on a single file)
  285.  
  286.     if (gDoOneFCB && gRefnum)
  287.     {
  288.         FCB *fcbp;
  289.  
  290.         gRefnum = (unsigned short) gRefnum;
  291.         if ((gRefnum > fcbslen) || ((gRefnum - 2) % fcbLen != 0))
  292.         {
  293.             PutPStr("\pBad file refnum ");
  294.             PutUHexWord(gRefnum);
  295.             PutLine();
  296.             return;
  297.         }
  298.  
  299.         fcbp = (FCB *) (gRefnum + fcbsbase);
  300.  
  301.         if (fcbp->fcbFlNum)
  302.         {
  303.             DrawHeader(false /* long form */);
  304.             DrawFCB(gRefnum, fcbp, false /* long form */);
  305.             return;
  306.         }
  307.  
  308.         PutPStr("\pFCB ");
  309.         PutUHexWord(gRefnum);
  310.         PutPStr("\p is not in use");
  311.         PutLine();
  312.         return;
  313.     }
  314.  
  315.  
  316.     // ••• handle 'file' and 'file 0' (show all open files, or abbreviated form of all files)
  317.  
  318.     {
  319.         int numFCBs = (fcbslen - 2) / fcbLen;
  320.         int fcbsUsed = 0;
  321.         int numFontsSkipped = 0;
  322.         Boolean foundOne = false;
  323.     
  324.         for (gRefnum = 2; gRefnum < fcbslen; gRefnum += fcbLen)
  325.         {
  326.             FCB* fcbp = (FCB *) (fcbsbase + gRefnum);
  327.  
  328.             if (paramPtr->aborted)
  329.                 return;
  330.  
  331.             if (!fcbp->fcbFlNum)    // if ______, skip this one
  332.                 continue;
  333.  
  334.             if (gHaveFileName && !PrefixPStr(filename, fcbp->fcbCName))
  335.                 continue;            // skip if it doesn't begin with specified name
  336.     
  337.             if (gFiletype && (gFiletype != fcbp->fcbFType))
  338.                 continue;
  339.     
  340.             fcbsUsed++;
  341.  
  342.             if (!foundOne++)                // draw header the first time
  343.                 DrawHeader(gDoOneFCB);        // true = short form ("file 0")
  344.  
  345.             if (gDoOneFCB && IsFontFile(fcbp))        // gDoOneFCB here means there was a refnum (0) on the command line
  346.                 numFontsSkipped++;
  347.             else
  348.                 DrawFCB(gRefnum, fcbp, gDoOneFCB /* true for short form (for 'file 0') */);
  349.         }
  350.  
  351.  
  352.         // summarize the results
  353.     
  354.         if (gHaveFileName)
  355.         {
  356.             if (!foundOne)
  357.             {
  358.                 PutPStr("\pNo open files match \"");
  359.                 PutPStr(filename);
  360.                 PutChar('"');
  361.                 PutLine();
  362.             }
  363.             return;
  364.         }
  365.  
  366.         if (gFiletype != 0)        // for now, don't summarize if we filtered by filetype
  367.             return;
  368.  
  369.         PutUDec(numFCBs);
  370.         PutPStr("\p FCBs, ");
  371.         PutUDec(fcbsUsed);
  372.         PutPStr("\p in use");
  373.  
  374.         if (numFontsSkipped)
  375.         {
  376.             PutPStr("\p (including ");
  377.             PutUDec(numFontsSkipped);
  378.             PutPStr("\p fonts not listed)");
  379.         }
  380.         PutPStr("\p, ");
  381.  
  382.         PutUDec(numFCBs - fcbsUsed);
  383.         PutPStr("\p free");
  384.         PutLine();
  385.     }
  386. }
  387.  
  388.  
  389. //----------------------------------------------------------------------------------------
  390. // CommandEntry:
  391. //----------------------------------------------------------------------------------------
  392. pascal void CommandEntry(dcmdBlock* paramPtr)
  393. {
  394.     switch (paramPtr->request)
  395.     {
  396.         case dcmdInit:
  397.             break;
  398.  
  399.         case dcmdHelp:
  400.             DoHelp();
  401.             break;
  402.  
  403.         case dcmdGetInfo:
  404.         {
  405.             static const char usageStr[] = "\p[fRefNum | \"file name\" | -t \"type\"]";
  406.  
  407.             * (long *) &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->dcmdVersion = 0x03032001; // version 3.0.3d1
  408.             BlockMoveData(&usageStr, &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->usageStr, usageStr[0]+1);
  409.             break;
  410.         }
  411.  
  412.         case dcmdDoIt:
  413.             dcmdSwapWorlds();
  414.             DoFileCommand(paramPtr);
  415.             dcmdSwapWorlds();
  416.             break;
  417.  
  418.         // Format 3 and newer dcmds must quietly ignore requests we don't recognize.
  419.  
  420.         default:
  421.             break;
  422.     }
  423. }
  424.